#define _USE_MATH_DEFINES

# include<iostream>
# include<cmath>
# include"EquationSolver.h"

using namespace::std;

/**
* @brief 仿函数类，实现给定函数y1的计算
* 
*/
class Fun1 : public Function
{
public:
    double operator()(double _x)
    {
        return (1/_x - tan(_x));
    }
};

/**
* @brief 仿函数类，实现给定函数y2的计算
* 
*/
class Fun2 : public Function
{
public:
    double operator()(double _x)
    {
        return (1/_x - exp2(_x));
    }
};

/**
* @brief 仿函数类，实现给定函数y3的计算
* 
*/
class Fun3 : public Function
{
public:
    double operator()(double _x)
    {
        return (exp2(-_x) + exp(_x) + 2*cos(_x) - 6);
    }
};

/**
* @brief 仿函数类，实现给定函数y4的计算
* 
*/
class Fun4 : public Function
{
public:
    double operator()(double x)
    {
        return ((x*x*x + 4*x*x + 3*x + 5) / (2*x*x*x - 9*x*x + 18*x -2));
    }
};

/**
* @brief 主函数
* 
*/
int main()
{
    cout << "Solution for Qustion B: " << endl;
    cout << "Test the bisection method. "  << endl;
    // 测试 Fun1
    Fun1 f1;
    Bisection Solve1(0.00001, M_PI/2-0.0001, 0.000001, 0.000001, 30, f1);
    double x1 = Solve1.solve();
    double y1 = f1(x1);
    cout << "Test for function1: the appropriate root is " << x1 << " , and f1(x1)= " << y1 << endl;
    
    // 测试 Fun2
    Fun2 f2;
    Bisection Solve2(0.00001, 1, 0.000001, 0.000001, 30, f2);
    double x2 = Solve2.solve();
    double y2 = f2(x2);
    cout << "Test for function2: the appropriate root is " << x2 << " , and f2(x2)= " << y2 << endl;
    
    // 测试 Fun3
    Fun3 f3;
    Bisection Solve3(1, 3, 0.000001, 0.000001, 50, f3);
    double x3 = Solve3.solve();
    double y3 = f3(x3);
    cout << "Test for function3: the appropriate root is " << x3 << " , and f3(x3)= " << y3 << endl;
    
    // 测试 Fun4
    Fun4 f4;
    Bisection Solve4(0, 4, 0.00000001, 0.000001, 30, f4);
    double x4 = Solve4.solve();
    double y4 = f4(x4);
    cout << "Test for function4: the appropriate root is " << x4 << " , and f4(x4)= " << y4 << endl;

    cout << "" << endl;

    return 0;
}
